<template>
  <div class="topology-root">
    <div style="display: none">
      <div class="popup-container" ref="popup">
        <div class="txt-item" v-for="(item,index) in popupData.businessFields">
          <div class="label">
            {{ item.alias }}
          </div>
          <div class="value">
            {{ `${item.value}${item.unit}` }}
          </div>

        </div>
        <div class="txt-item" v-if="popupData.status != null && popupData.status !== ''">
          <div class="label">
            状态
          </div>
          <div class="value">
            <el-switch
                @change="changePointData"
                :active-value="1"
                :inactive-value="2"
                v-model="popupData.status"
                class="ml-2"
                style=" --el-switch-off-color: #e59047"
            />
          </div>
        </div>
      </div>
    </div>
    <div id="map" class="map-container"></div>
  </div>
</template>

<script setup>
import {Scene, PointLayer, LineLayer, Popup} from '@antv/l7';
import {GaodeMap} from '@antv/l7-maps';
// 水泵
import waterPump from '@/assets/images/map/waterPump.png'
// 村庄
import village from '@/assets/images/map/village.png'
// 监测设备
import monitoringEquipment from '@/assets/images/map/monitoringEquipment.png'
// 流量计
import flowmeter from '@/assets/images/map/flowmeter.png'
import flowmeterDisabled from '@/assets/images/map/flowmeterDisabled.png'
// 方向箭头
import direction from '@/assets/images/map/direction.png'
import pointData from '@/datas/pointData.json'
import lineData from '@/datas/lineData.json'

const {proxy} = getCurrentInstance();

const villagePointType = 'village'
const monitoringEquipmentPointType = 'monitoringEquipment'
const flowmeterPointType = 'flowmeter'
const waterPumpPointType = 'waterPump'
const directionPointType = 'direction'

const openPopupPointTypes = [monitoringEquipmentPointType, flowmeterPointType]

let scene = null

const mapLogoVisible = false
const mapId = 'map'

let pointLayer = null;

const popupOpenTrigger = 'click'

let popupData = ref({
  pointType: '',
  featureId: '',
  lng: '',
  lat: '',
  businessFields: [],
  status: ''
})

let pointLayerSource = null

let layerPopup = null

function initPointLayerSource() {
  pointLayerSource = pointLayer.getSource();
}

function changePointData(status) {
  pointLayerSource.updateFeaturePropertiesById(popupData.value.featureId, {status});
}

function createScene() {
  scene = new Scene({
    logoVisible: mapLogoVisible,
    id: mapId,
    map: new GaodeMap({
      pitch: 0,
      style: 'blank ',
      center: [121.435159, 31.256971],
      zoom: 14.89,
      minZoom: 10,
      token: '9aee6df17557d9025c07bdcb52ae2a90'
    })
  });
}

function setMapStatus() {
  const mapHandleStatus = false
  const IStatusOptions = {
    showIndoorMap: mapHandleStatus,
    resizeEnable: mapHandleStatus,
    dragEnable: mapHandleStatus,
    keyboardEnable: mapHandleStatus,
    doubleClickZoom: mapHandleStatus,
    zoomEnable: mapHandleStatus,
    rotateEnable: mapHandleStatus,
  }
  scene.setMapStatus(IStatusOptions)
}

function addLineLayerData() {
  const shapeType = 'line'
  const lineSize = 3
  const baseLineLayer = new LineLayer()
      .source(lineData, {
        parser: {
          type: 'json',
          coordinates: 'coord'
        }
      })
      .size(lineSize)
      .shape(shapeType)
      .texture('direction')
      .color('rgb(22,119,255)')
      .animate({
        interval: 1, // 间隔
        duration: 1, // 持续时间，延时
        trailLength: 2 // 流线长度
      })
      .style({
        opacity: 0.6,
        lineTexture: true, // 开启线的贴图功能
        iconStep: 10, // 设置贴图纹理的间距
        borderWidth: 0.4, // 默认文 0，最大有效值为 0.5
        borderColor: '#fff' // 默认为 #ccc
      });

  scene.addLayer(baseLineLayer)
}

function addMapImageSource() {
  // 图片列表
  const imageList = [
    {
      imageId: 'flowmeterDisabled',
      imageUrl: flowmeterDisabled
    },
    {
      imageId: directionPointType,
      imageUrl: direction
    },
    {
      imageId: waterPumpPointType,
      imageUrl: waterPump
    },
    {
      imageId: villagePointType,
      imageUrl: village
    },
    {
      imageId: monitoringEquipmentPointType,
      imageUrl: monitoringEquipment
    },
    {
      imageId: flowmeterPointType,
      imageUrl: flowmeter
    }
  ]
  imageList.forEach(({imageId, imageUrl}) => {
    scene.addImage(imageId, imageUrl);
  })
}

function addPointLayer() {
  const waterPumpImageSize = [50, 60];
  const villageImageSize = 30
  const monitoringEquipmentImageSize = 30
  const flowmeterImageSize = 25
  const mapOpacity = 1
  pointLayer = new PointLayer()
      .source(pointData)
      .size('pointType', (pointType) => {
        switch (pointType) {
          case waterPumpPointType:
            return waterPumpImageSize;
          case villagePointType:
            return villageImageSize;
          case monitoringEquipmentPointType:
            return monitoringEquipmentImageSize;
          case flowmeterPointType:
            return flowmeterImageSize;
        }
      }).style({
        opacity: mapOpacity,
      });
  scene.addLayer(pointLayer);
  changePointLayerShape()
}

function changePointLayerShape() {
  pointLayer.shape(['pointType', 'id', 'status'], function (pointType, id, status) {
    let resPointIcon = pointType
    if (pointType === flowmeterPointType) {
      switch (status) {
        case 1:
          resPointIcon = pointType
          break
        case 2:
          resPointIcon = 'flowmeterDisabled'
      }
    }
    return resPointIcon;
  });

}

function getPopupTemplate() {
  return proxy.$refs.popup
}

function setPopupData(properties) {
  let {pointType, businessFields, status, featureId, lng, lat} = properties;
  popupData.value.pointType = pointType
  popupData.value.businessFields = businessFields || []
  popupData.value.status = status || ''
  popupData.value.featureId = featureId
  popupData.value.lng = lng
  popupData.value.lat = lat
}

function getOpenPopupFlagByPointType(pointType) {
  return openPopupPointTypes.some(allowedType => allowedType === pointType)
}

function addPointLayerClickLis() {
  pointLayer.on(popupOpenTrigger, (e) => {
    recordCurrentPoint(e)
    openPopup()
  });
  pointLayer.on('unpick', closePopup);
}

function recordCurrentPoint(e) {
  let {featureId, feature: {properties, geometry: {coordinates: [lng, lat]}}} = e;
  setPopupData({...properties, featureId, lng, lat})
}

function openPopup(e) {
  closePopup()
  if (!getOpenPopupFlagByPointType(popupData.value.pointType)) {
    return
  }
  let {value: {lng, lat}} = popupData
  layerPopup = new Popup({
    closeButton:false,
    lngLat: {lng, lat,},
    html: getPopupTemplate(),
  });
  scene.addPopup(layerPopup);
}

function closePopup() {
  if (!layerPopup) {
    return
  }
  scene.removePopup(layerPopup);
  layerPopup = null
}

function initMap() {
  createScene()
  scene.on('loaded', () => {
    setMapStatus()
    addMapImageSource()
    addLineLayerData()
    addPointLayer()
    addPointLayerClickLis()
    initPointLayerSource()
  });
}

onMounted(() => {
  nextTick(() => {
    initMap()
  })
})
</script>

<style scoped lang="scss">
.topology-root {
  height: 100%;
  width: 100%;
  position: relative;
  background-image: url("@/assets/images/map/sytp.png");
  background-size: 100% 100%;

  .map-container {
    height: 100%;
    width: 100%;
  }

  ::v-deep .amap-container {
    background-image: none;
    background-color: transparent;
  }

  ::v-deep .l7-popup-tip {
    border-top-color: #00FFFF;
  }

  ::v-deep .l7-popup-content {
    background: transparent;
    padding: 0;
  }

  .popup-container {
    background-image: url("@/assets/images/map/popUpBackground.png");
    background-size: 100% 100%;
    font-size: 18px;
    color: #FFFFFF;
    padding: 40px;

    .txt-item {
      display: flex;
      width: 200px;
      height: 28px;

      .label, .value {
        width: 50%;
        height: 100%;
      }
    }
  }
}
</style>
